#include "display_bmp.h"
#include "font.h"

Display_bmp::Display_bmp()
{
   led_fd=open("/dev/fb0", O_RDWR);
   fb_addr=(unsigned int *)mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED, led_fd, 0);
   f = fontLoad((char *)"/usr/share/fonts/DroidSansFallback.ttf");//打开字体

}

void Display_bmp::display_point_to_screen(int x, int y, int color, unsigned int *fb_addr)
{
    *(fb_addr + 800 * y + x) = color;
}


Display_bmp::~Display_bmp()
{
    fontUnload(f);//关闭字体
    munmap(fb_addr,800*480*4);
    close(led_fd);
}

//中文字库
void Display_bmp::displayfont(int x,int y,char* info,int width,int red,int green,int blue)
{
   
    //设置字体的大小 
    fontSetSize(f, 40);
   
    //指定输出框的颜色
    Sketchpad=createBitmapWithInit(width,50,4,getColor(0,red,green,blue));
   
    //把字体输出到输出框中
    fontPrint(f,Sketchpad,0,0,info,getColor(0,0,0,0),0);
   
    //把输出框的所有信息显示到LCD屏幕中 
    show_font_to_lcd(fb_addr,x,y,Sketchpad);
    
}

int Display_bmp::display_picture_for_bmp_format(int start_x, int start_y, const char *pic_name, float mul)
{
    FILE *pic_fp;
    size_t rd_blk;
    bmp_color_t *buffer, *pos;
    unsigned int color;
    int x, y;
    char head[54];
    int width;
    int height;
    unsigned int file_size;
    int row_size;
    int end_x, end_y;

    if (strcmp(pic_name, "backgroud") == 0) //背景
    {

        for (y = 0; y < 480 && y >= 0; y++)
        {
            for (x = 0; x < 800 && x >= 0; x++)
            {
                color = 0xA020F0;

                display_point_to_screen(x, y, color, fb_addr);
            }
        }
        return 0;
    }

    //打开图片
    pic_fp = fopen(pic_name, "r");
    if (pic_fp == NULL)
    {
        fprintf(stderr, "打开%s图片文件失败:%s\n", pic_name, strerror(errno));
        return -1;
    }

    //分析前面54字节的信息
    fread(head, sizeof(head), 1, pic_fp);

    file_size = *(unsigned int *)&head[2]; //文件大小

    width = *(unsigned int *)&head[18];  //获取图片宽度
    height = *(unsigned int *)&head[22]; //获取图片高度

    // printf("file_size=%u, width=%u, height=%u\n", file_size, width, height);

    //读取文件数据
    buffer = (bmp_color_t *)malloc(file_size - 54);

    if (buffer == NULL)
    {
        perror("申请缓冲BMP图片的内存失败");
        goto request_bmp_memory_err;
    }

    rd_blk = fread(buffer, sizeof(bmp_color_t) * width, height, pic_fp);
    if (rd_blk != height)
    {
        if (ferror(pic_fp))
            fprintf(stderr, "读取%s图片数据出错:%s\n", pic_name, strerror(errno));
        else
            fprintf(stderr, "读取的bmp图片数据有可能破损了，数据量不足\n");

        goto get_bmp_data_err;
    }

    //关闭文件
    fclose(pic_fp);

    row_size = width * 3;
    while (row_size % 4 != 0)
        row_size++;

    // printf("一行有%d个字节\n", row_size);

    end_x = start_x + width;
    end_x *= mul;
    end_y = start_y + height;
    end_y *= mul;

    float distance;
    float pic_x_pos, pic_y_pos;
    bmp_color_t *row_pos;

    distance = 1 / mul; //得出循环图片时的长度距离

    //把图片显示出来
    for (y = start_y, pic_y_pos = 0; y < end_y && y < 480 && y >= 0; y++, pic_y_pos += distance)
    {
        row_pos = (bmp_color_t *)((char *)buffer + ((int)pic_y_pos) * row_size); //拿到当前这行的数据首地址

        for (x = start_x, pic_x_pos = 0; x < end_x && x < 800 && x >= 0; x++, pic_x_pos += distance)
        {
            pos = row_pos + (int)pic_x_pos;

            color = 0 << 24 | pos->red << 16 | pos->green << 8 | pos->blue; // A<<24|R<<16|G<<8|B
            display_point_to_screen(x, end_y - y + start_y - 1, color, fb_addr);
        }
    }

    free(buffer);

    return 0;

    get_bmp_data_err:
    free(buffer);
    request_bmp_memory_err:
    fclose(pic_fp);
    return -1;
}
